import org.lobobrowser.gui._
import org.lobobrowser.main._
import org.lobobrowser.ua._
import scala.collection.immutable._
import java.util.{Date,HashMap,Scanner}
import java.io._
import java.text._
import java.util.regex.Pattern
import java.net.URL

class BrowserApp 
{
	//will contain sessions with index mapping
	private var sessions:HashMap[Int,FramePanel] = new HashMap() 
	
	private var numOfSessions 		= 1
	
	private var nextSessionId 		= 0
	
	private var curActiveSession	= 1
	
	private var homeURL 			= "http://google.com"
		
	// This optional step initializes logging so only warnings
	// are printed out.
	PlatformInit.getInstance().initLogging(false);

	// This step is necessary for extensions to work:
	PlatformInit.getInstance().init(false, false);
	
	//first session contain homepage
	var activeSession = new FramePanel()
	activeSession.navigate(homeURL)
	sessions.put(nextSessionId,activeSession)
	nextSessionId = nextSessionId + 1
		
	def newSession():Int =
	{ 
		var fp = new FramePanel()
		fp.addNavigationListener(new NavigationListener()
		{
		  def beforeLocalNavigate(event:NavigationEvent){}
		  def beforeWindowOpen(event:NavigationEvent){}
		  def beforeNavigate(event:NavigationEvent)
		  {
		    addHistory(event.getOriginatingFrame().getCurrentNavigationEntry())
		  }
		  
		})
		sessions.put(nextSessionId,fp)
		nextSessionId = nextSessionId + 1
		numOfSessions  = numOfSessions +1
		return (nextSessionId - 1)
	}
	
	def deleteSession(Id:Int)
	{
		sessions.remove(Id)
	}
	
	//so that GUI can replace previouse session with new
	def setActiveSession(Id:Int):FramePanel =
	{
		var s = sessions.get(Id)
		if (s != null) activeSession  = s
		return s
	}
	
	def canBack():Boolean = 
	{
		return activeSession.canBack()
	}
	
	def back() 
	{
		activeSession.back()
	}
	
	def canForward():Boolean = 
	{
		return activeSession.canForward()
	}
	
	def forward()
	{
		activeSession.forward()
	}
	
	def navigate(url:String)
	{
	  var u:URL = null
	  try 
	  {	
	    u  = new URL(url)
	  }
	  catch 
	  {
	    case e:Exception => u = new URL("http://www.google.com/search?q="+url) 	    
	  }
		
	  activeSession.navigate(u)	  
	}
	
	def reload()
	{
		activeSession.reload()
	}
	
	def home()
	{
		activeSession.navigate(homeURL)
	}
	
	def getHomeURL():String = 
	{
		return homeURL
	}
	
	def setHomeURL(url:String)
	{
		homeURL = url
	}
	
	def getStatus():String =
	{
		activeSession.getStatus()
	}
	
	def getUrl():String =
	{
		return activeSession.getCurrentNavigationEntry().getUrl().toString()
	}
	
	//for dual display
	def getDualContent(anotherSessionId:Int):FramePanel = 
	{
		var s = sessions.get(anotherSessionId)
		return s
	}
	
	//general text manipulation functions
	def appendEntryTofile(entry:NavigationEntry,file:String)
	{
		var fw:FileWriter = new FileWriter(file,true)
		var s = "("+entry.getTitle()+")"+"  "+"("+entry.getUrl()+")"+"\n" 
		fw.write(s)
		fw.close()
	}
	
	def parseLine(line:String,numOfTokens:Int):Array[String] = 
	{
			var arr = new Array[String](numOfTokens)
			var reg = ""
			var i = 0
			
			//creating pattern
			while(i < numOfTokens - 1)
			{
				reg+="\\(("+".+"+")\\)"+"\\s\\s"
			}
			reg+="\\(("+".+"+")\\)"
			
			var p  = Pattern.compile(reg)
			var m = p.matcher(line)
			if (m.matches())
			{
				i = 0
				while(i < numOfTokens)
				{
					arr(i) = m.group(i+1)
				}
			}
			return arr
	}
	
	
	//bookmarks
	def addBookmark()
	{
		appendEntryTofile(activeSession.getCurrentNavigationEntry(),"Bookmarks")
	}
	
	def getBookmarks():List[(String,String)] = 
	{
		var l:List[(String,String)] = List()
		var scan = new Scanner(new FileReader("Bookmarks"))
		while (scan.hasNextLine())
		{
		  var line = scan.nextLine()
		  var a = parseLine(line,2)
		  l:+=(a(0),a(1))
		}
		return l
	}
	
	//history
	def addHistory(entry:NavigationEntry)
	{	
		var d = new Date()
		var sdf = new SimpleDateFormat("dd.MM.yyyy 'at' HH:mm:ss")
		var fw:FileWriter = new FileWriter("History",false)
		var s = sdf.format(d)
		fw.write(s)
		fw.close()
		appendEntryTofile(entry,"History")
	}
	
	def getHistory():List[(String,String,String)] = 
	{
		var l:List[(String,String,String)] = List()
		var scan = new Scanner(new FileReader("Bookmarks"))
		var count = 0
		while (scan.hasNextLine() && (count < 100))
		{
		  count+=1
		  var line = scan.nextLine()
		  var a = parseLine(line,3)
		  l:+=(a(0),a(1),a(2))
		}
		return l
	}
	
}